﻿using NHibernate.Mapping.ByCode;
using NHibernate.Mapping.ByCode.Conformist;

namespace Mammoth.Entities
{
    public class EntityMapping<T> : ClassMapping<T> where T : Entity
    {
        public EntityMapping()
        {
            Id(x => x.Id, x => x.Generator(Generators.Identity));
            Property(x => x.CreateDate);
        }
    }

    public class KeywordEntityMapping : EntityMapping<KeywordEntity>
    {
        public KeywordEntityMapping()
        {
            Table("tabel_keyword");
            Property(x => x.Keyword);
            Property(x => x.Description);
        }
    }

    public class InboxEntityMapping : EntityMapping<InboxEntity>
    {
        public const int MessageLength = 2000;

        public InboxEntityMapping()
        {
            Table("tabel_inbox");
            Property(x => x.Message, m => m.Length(MessageLength));
            ManyToOne<AccountEntity>(x => x.Service,
                m =>
                {
                    m.Column(c => c.Name("AccountId"));
                    m.Lazy(LazyRelation.NoLazy);
                });
            ManyToOne<BuddyEntity>(x => x.Buddy,
                m =>
                {
                    m.Column(c => c.Name("ClientId"));
                    m.Lazy(LazyRelation.NoLazy);
                });
        }
    }

    public class OutboxEntityMapping : EntityMapping<OutboxEntity>
    {
        public const int MessageLength = 2000;

        public OutboxEntityMapping()
        {
            Table("tabel_outbox");
            Property(x => x.Message, m => m.Length(MessageLength));
            ManyToOne<AccountEntity>(x => x.Service,
                m =>
                {
                    m.Column(c => c.Name("AccountId"));
                    m.Lazy(LazyRelation.NoLazy);
                });
            ManyToOne<BuddyEntity>(x => x.Buddy,
                m =>
                {
                    m.Column(c => c.Name("ClientId"));
                    m.Lazy(LazyRelation.NoLazy);
                });
        }
    }

    public class AccountEntityMapping : EntityMapping<AccountEntity>
    {
        public const int EmailLength = 256;
        public const int NameLength = 128;

        public AccountEntityMapping()
        {
            Table("tabel_account");
            Property(x => x.Email, m => m.Length(EmailLength));
            Property(x => x.Name, m => m.Length(NameLength));
            Bag<OutboxEntity>(x => x.Outbox,
                p =>
                {
                    p.Key(k => k.Column(c => c.Name("AccountId")));
                },
                r => r.OneToMany());
            Bag<InboxEntity>(x => x.Inbox,
                p =>
                {
                    p.Key(k => k.Column(c => c.Name("AccountId")));
                },
                r => r.OneToMany());
        }
    }

    public class BuddyEntityMapping : EntityMapping<BuddyEntity>
    {
        public const int EmailLength = 256;
        public const int ServiceEmailLength = 256;
        public const int NameLength = 128;
        
        public BuddyEntityMapping()
        {
            Table("tabel_client");
            Property(x => x.Email, m => m.Length(EmailLength));
            Property(x => x.ServiceEmail, m => m.Length(ServiceEmailLength));
            Property(x => x.Name, m => m.Length(NameLength));
            Bag<InboxEntity>(x => x.Inbox,
                p =>
                {
                    p.Key(k => k.Column(c => c.Name("ClientId")));
                },
                r => r.OneToMany());
            Bag<OutboxEntity>(x => x.Outbox,
                p =>
                {
                    p.Key(k => k.Column(c => c.Name("ClientId")));
                },
                r => r.OneToMany());
            Bag<OrderEntity>(x => x.Orders, 
                p => {
                    p.Key(k => k.Column(c => c.Name("ClientId")));
                }, 
                r => r.OneToMany());
            OneToOne<BroadcastSubscriberEntity>(x => x.BroadcastSubscribe, 
                m => m.Lazy(LazyRelation.NoLazy));
        }
    }

    public class BroadcastSubscriberMapping : EntityMapping<BroadcastSubscriberEntity>
    {
        public BroadcastSubscriberMapping()
        {
            Table("tabel_pelanggan_broadcast");
            Property(x => x.IsActive);
            OneToOne<BuddyEntity>(x => x.Buddy, m => m.Lazy(LazyRelation.NoLazy));
        }
    }

    public class OrderMapping : EntityMapping<OrderEntity>
    {
        public OrderMapping()
        {
            Table("tabel_order");
            ManyToOne<ValasEntity>(x => x.RequestedValas, 
                m => {
                    m.Column(c => c.Name("ValasId"));
                    m.Lazy(LazyRelation.NoLazy); 
                });
            ManyToOne<BuddyEntity>(x => x.Customer, 
                m => {
                    m.Column(c => c.Name("ClientId"));
                    m.Lazy(LazyRelation.NoLazy); 
                });
            Property(x => x.IsValid);
            Property(x => x.IsCommited);
        }
    }

    public class ValasEntityMapping : EntityMapping<ValasEntity>
    {
        public const int NameLength = 15;
        
        public ValasEntityMapping()
        {
            Table("tabel_valas");
            Property(x => x.Name);
            Property(x => x.Sell);
            Property(x => x.Buy1);
            Property(x => x.Buy2);
            Property(x => x.Buy3);
            Property(x => x.Type1);
            Property(x => x.Type2);
            Property(x => x.Type3);
            Bag<OrderEntity>(x => x.Orders, 
                p => {
                    p.Key(k => k.Column(c => c.Name("ValasId")));
                }, 
                r => r.OneToMany());
        }
    }
}
